package com.itlong.cloud.operate.service.impl;

import com.itlong.cloud.POJO.DTO.operate.OperatePushInfoPageDTO;
import com.itlong.cloud.POJO.DTO.operate.OperateSavePushInfoDTO;
import com.itlong.cloud.POJO.PO.AppUserReadPushRecordPO;
import com.itlong.cloud.POJO.PO.PushInfoPO;
import com.itlong.cloud.POJO.PO.PushInfoProjectPO;
import com.itlong.cloud.POJO.VO.operate.OperateAppPushDataVO;
import com.itlong.cloud.POJO.VO.operate.OperateProjectInfoVO;
import com.itlong.cloud.POJO.VO.operate.OperatePushInfoOneVO;
import com.itlong.cloud.POJO.VO.operate.OperatePushInfoVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.enumerate.DataStatusEnum;
import com.itlong.cloud.operate.dao.IOperatePushInfoDao;
import com.itlong.cloud.operate.dao.IOperatePushInfoProjectDao;
import com.itlong.cloud.operate.service.IOperatePushInfoService;
import com.itlong.cloud.utils.data.handler.SqlUtil;
import com.itlong.cloud.utils.date.DateUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.random.LogicIdUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <desc>
 *      运营-运营管理-消息推送服务接口实现类。
 * <desc/>
 *
 * @createDate 2017/9/28.
 */
@Service
public class OperatePushInfoServiceImpl implements IOperatePushInfoService {

    private static final Logger LOG = LoggerFactory.getLogger(OperatePushInfoServiceImpl.class);

    @Autowired
    IOperatePushInfoDao iOperatePushInfoDao;

    @Autowired
    IOperatePushInfoProjectDao iOperatePushInfoProjectDao;

     /**
      * <desc>
      *      保存消息推送信息。
      * <desc/>
      *
      * @param  pushInfoDTO
      * @return 返回影响行数
      * @author shengen.T
      * @createDate 2017/9/28
      */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Integer savePushInfo(OperateSavePushInfoDTO pushInfoDTO) throws Exception {

        // 先校验是否已执行过旧数据处理接口
        PushInfoPO executeMark = iOperatePushInfoDao.getExecuteMark();
        if (executeMark == null || StringUtils.isBlank(executeMark.getPushInfoId())) {
            return -1;
        }

        Integer flag = 1;
        // 如果是云空间服务费到期提醒数据，判断，不要重复添加
        if (pushInfoDTO.getInfoType() == 0) {
            // 该项目下，今天的时间已经创建了云空间服务费到期提醒，则不再创建，云空间服务费到期提醒数据时app getUserInfo接口触发，项目id只有一个
            Integer pushCount = iOperatePushInfoDao.getPushInfoTodayCount(pushInfoDTO.getProjectIds());
            if (pushCount > 0) {
                return flag;
            }
        }
        //保存消息推送内容
        PushInfoPO pushInfoPO = new PushInfoPO(LogicIdUtil.bussinessId(),
                pushInfoDTO.getInfoType(),
                pushInfoDTO.getInfoContent(),
                DataStatusEnum.NORMAL.getType(),
                pushInfoDTO.getBeginDate(),
                pushInfoDTO.getEndDate(),
                new Date(),
                new Date()
        );
        pushInfoPO.setTitle(pushInfoDTO.getTitle());
        pushInfoPO.setPublishPlatform(pushInfoDTO.getPublishPlatform());
        pushInfoPO.setVersionInfo(pushInfoDTO.getVersionInfo());
        Integer pushInfoCount = iOperatePushInfoDao.save(SqlUtil.durableData(pushInfoPO, PlatformConstants.TABLE_SAVE));
        // 云服务费信息时，小程序平台类型也添加一条
        if (pushInfoDTO.getInfoType() == 0) {
            pushInfoPO.setPublishPlatform(2);
            pushInfoCount += iOperatePushInfoDao.save(SqlUtil.durableData(pushInfoPO, PlatformConstants.TABLE_SAVE));
        }

        //保存推送消息和项目对应信息
        String projectId[] = StringHandlerUtil.splitString(pushInfoDTO.getProjectIds());
        PushInfoProjectPO pushInfoProjectPO = new PushInfoProjectPO();
        Integer pushProjectCount = 0;
        for (int i = 0; i < projectId.length; i++) {
            pushInfoProjectPO.setProjectId(projectId[i]);
            pushInfoProjectPO.setPushInfoId(pushInfoPO.getPushInfoId());
            pushProjectCount += iOperatePushInfoProjectDao.save(SqlUtil.durableData(pushInfoProjectPO, PlatformConstants.TABLE_SAVE));
        }
        if ((pushInfoCount < 1) || (pushProjectCount < 1)) {
            flag = 0;
        }
        return flag;
    }

     /**
      * <desc>
      *      修改消息推送信息。
      * <desc/>
      *
      * @param  pushInfoDTO
      * @return  返回影响行数
      * @author shengen.T
      * @createDate 2017/9/28
      */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Integer updatePushInfo(OperateSavePushInfoDTO pushInfoDTO) throws Exception{

        // 先校验是否已执行过旧数据处理接口
        PushInfoPO executeMark = iOperatePushInfoDao.getExecuteMark();
        if (executeMark == null || StringUtils.isBlank(executeMark.getPushInfoId())) {
            return -1;
        }

        Integer flag = 1;
        //保存消息推送内容
        PushInfoPO pushInfoPO = new PushInfoPO(pushInfoDTO.getPushInfoId(),
                pushInfoDTO.getInfoType(), //消息类型 1-运营 2-物业
                pushInfoDTO.getInfoContent(),
                pushInfoDTO.getStatus(),
                pushInfoDTO.getBeginDate(),
                pushInfoDTO.getEndDate(),
                null,
                new Date()
        );
        pushInfoPO.setTitle(pushInfoDTO.getTitle());
        pushInfoPO.setPublishPlatform(pushInfoDTO.getPublishPlatform());
        pushInfoPO.setVersionInfo(pushInfoDTO.getVersionInfo());
        Integer pushInfoCount = iOperatePushInfoDao.update(SqlUtil.durableData(pushInfoPO, PlatformConstants.TABLE_UPDATE));

        //保存推送消息和项目对应信息
        String projectId[] = StringHandlerUtil.splitString(pushInfoDTO.getProjectIds());
        if (projectId.length < 1) {
            return pushInfoCount < 1 ? 0 : flag;
        }
        iOperatePushInfoProjectDao.delete(pushInfoPO.getPushInfoId());  //删除推送消息和项目对应信息
        PushInfoProjectPO pushInfoProjectPO = new PushInfoProjectPO();
        Integer pushProjectCount = 0;
        for (int i = 0; i < projectId.length; i++) {
            pushInfoProjectPO.setProjectId(projectId[i]);
            pushInfoProjectPO.setPushInfoId(pushInfoPO.getPushInfoId());
            pushProjectCount += iOperatePushInfoProjectDao.save(SqlUtil.durableData(pushInfoProjectPO, PlatformConstants.TABLE_SAVE));
        }
        if ((pushInfoCount < 1) || (pushProjectCount < 1)) {
            flag = 0;
        }
        return flag;
    }

     /**
      * <desc>
      *      删除消息推送。
      * <desc/>
      *
      * @param  pushInfoIds
      * @return  返回影响行数
      * @author shengen.T
      * @createDate 2017/9/28
      */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Integer deletePushInfo(String pushInfoIds) throws Exception{
        String pushInfoId[] = StringHandlerUtil.splitString(pushInfoIds);
        //逻辑删除消息推送
        iOperatePushInfoDao.delete(pushInfoId);
        //删除消息项目关系表
        iOperatePushInfoDao.deleteBatch(pushInfoId);
        // 删除app用户读取推送（系统消息，小区通知）记录
        iOperatePushInfoDao.deleteAppReadPushBatch(pushInfoId);
        return 1;
    }

     /**
      * <desc>
      *      根据推送消息ID获取详细信息。
      * <desc/>
      *
      * @param  pushInfoId
      * @return
      * @author shengen.T
      * @createDate 2017/9/28
      */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public OperatePushInfoOneVO getPushInfo(String pushInfoId) throws Exception{
        OperatePushInfoOneVO operatePushInfoOneVO =  iOperatePushInfoDao.getOne(pushInfoId);
        if(operatePushInfoOneVO!=null && StringUtils.isNotBlank(operatePushInfoOneVO.getPushInfoId())){
            List<OperateProjectInfoVO> projectInfoList = iOperatePushInfoDao.getProjectList(pushInfoId);
            operatePushInfoOneVO.setProjectInfos(projectInfoList);
        }
        return  operatePushInfoOneVO;
    }

     /**
      * <desc>
      *      获取推送消息分页信息。
      * <desc/>
      *
      * @param  pageDTO 分页请求参数对象
      * @return
      * @author shengen.T
      * @createDate 2017/9/28
      */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Page<OperatePushInfoVO> getPushInfoPage(OperatePushInfoPageDTO pageDTO) throws Exception{
        //将DTO转换为Map params
        Map<String, Object> params = SqlUtil.convertBeanToMapParams(pageDTO);
        //分页类默认pageSize为20
        Page<OperatePushInfoVO> page = new Page<>();
        page.getPage().setPageSize(pageDTO.getPageSize());
        page.getPage().setCurrentPage(pageDTO.getCurrentPage());
        params.put("currentPage",page.getPage().getStartSlip());
        params.put("pageSize",page.getPage().getPageSize());
        //填充返回数据集
        page.setRows(iOperatePushInfoDao.getPage(params),iOperatePushInfoDao.getPageCount(params));
        return page;

    }

     /**
      * <desc>
      *       获取允许推送消息的列表信息。
      * <desc/>
      *
      * @param
      * @return
      * @author shengen.T
      * @createDate 2017/10/26
      */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<OperatePushInfoVO> getEnabledPushInfoList() throws Exception{
        return iOperatePushInfoDao.getEnabledPushInfoList(new Date());
    }


     /**
      * <desc>
      *      批量设置发布状态。(1已推送,2待推送,3已过期)
      * <desc/>
      *
      * @param  pushInfoIds 消息ID列表
      * @return
      * @author shengen.T
      * @createDate 2017/10/26
      */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Integer setPushStatus(String pushInfoIds) throws Exception{
        String pushInfoId[] = StringHandlerUtil.splitString(pushInfoIds);
        return iOperatePushInfoDao.setStatus(pushInfoId,1);
    }

    /**
     * <desc>
     * 获取当前时间某项目允许推送的最新推送消息
     * <desc/>
     *
     * @param projectId 项目id
     * @return
     * @author Chunjian.G
     * @createDate 2017-11-08
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<String> getLatestPushContent(String projectId) throws Exception {
        return iOperatePushInfoDao.getLatestPushContent(projectId, new Date());
    }

    /**
     * <desc>
     *      获取过期消息推送列表。
     * <desc/>
     *
     * @param  nowTime 系统当前时间
     * @return true更新状态成功 false 更新状态失败
     * @author shengen.T
     * @createDate 2017-12-04
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public boolean checkOverDatePushInfoList(Date nowTime) throws Exception{
        //获取需要更新状态的列表消息ID
        List<String> pushIdList = iOperatePushInfoDao.getOverDatePushIdList(nowTime);
        if((pushIdList!=null)&&(pushIdList.size()>0)){
            String[] toBeStored = new String[pushIdList.size()];
            pushIdList.toArray(toBeStored);
            //更新过期消息状态为 3已过期
           Integer res =  iOperatePushInfoDao.setStatus(toBeStored,3);
           if(res>0){
               return true;
           }
        }
        return false;
    }

    /**
     * <desc>
     *      获取当前时间某项目允许推送的最新推送消息标题
     * <desc/>
     *
     * @param projectId 项目id
     * @return
     * @author Juguang.S
     * @createDate 2019-08-28
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<String> getLatestPushTitle(String projectId) throws Exception {
        return iOperatePushInfoDao.getLatestPushTitle(projectId, new Date());
    }

    /**
     * <desc>
     *      获取app历史版本号列表
     * </desc>
     *
     * @author wangzhi
     * @createDate 2020/04/29
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<String> getAppVersionList() throws Exception {
        return iOperatePushInfoDao.getAppVersionList();
    }

    /**
     * <desc>
     *      处理旧推送数据，一次性接口，将原来的app推送数据复制一份作为小程序的推送数据，发布后第一时间运行该接口
     * </desc>
     *
     * @author wangzhi
     * @createDate 2020/04/29
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Integer copyAppPushInfoToMiniProgram() throws Exception {
        // 先校验是否已执行过
        PushInfoPO executeMark = iOperatePushInfoDao.getExecuteMark();
        if (executeMark != null && StringUtils.isNotBlank(executeMark.getPushInfoId())) {
            return -1;
        }

        Date nowTime = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat(DateUtil.DATE_FORMAT_TYPE1);
        // 添加一个执行该接口的标记并持久化，防止多次执行造成脏数据
        PushInfoPO markPushInfoPO = new PushInfoPO("itlMark", 9, "执行数据复制接口标识，此条数据表示已执行", 0,
                sdf.format(nowTime), sdf.format(nowTime), nowTime, nowTime);
        markPushInfoPO.setTitle("标识数据");
        markPushInfoPO.setPublishPlatform(9);
        markPushInfoPO.setVersionInfo(null);
        iOperatePushInfoDao.save(SqlUtil.durableData(markPushInfoPO, PlatformConstants.TABLE_SAVE));

        // 处理数据
        Integer rows = 0;
        List<OperateAppPushDataVO> operateAppPushDataVOList = iOperatePushInfoDao.getAppPushData();
        if (operateAppPushDataVOList != null && !operateAppPushDataVOList.isEmpty()) {
            rows = operateAppPushDataVOList.size();
            List<PushInfoPO> pushInfoPOList = new ArrayList<>();
            List<PushInfoProjectPO> pushInfoProjectPOList = new ArrayList<>();
            List<AppUserReadPushRecordPO> appUserReadPushRecordPOList = new ArrayList<>();
            for (OperateAppPushDataVO operateAppPushDataVO : operateAppPushDataVOList) {
                String pushInfoId = LogicIdUtil.bussinessId();
                PushInfoPO pushInfoPO = new PushInfoPO();
                pushInfoPO.setPushInfoId(pushInfoId);
                pushInfoPO.setInfoType(operateAppPushDataVO.getInfoType());
                pushInfoPO.setPublishPlatform(2);
                pushInfoPO.setInfoContent(operateAppPushDataVO.getInfoContent());
                pushInfoPO.setStartTime(operateAppPushDataVO.getStartTime());
                pushInfoPO.setEndTime(operateAppPushDataVO.getEndTime());
                pushInfoPO.setCreateTime(sdf.parse(operateAppPushDataVO.getCreateTime()));
                pushInfoPO.setUpdateTime(nowTime);
                pushInfoPO.setStatus(DataStatusEnum.NORMAL.getType());
                pushInfoPO.setTitle(operateAppPushDataVO.getTitle());
                pushInfoPOList.add(pushInfoPO);
                if (StringUtils.isNotBlank(operateAppPushDataVO.getProjectId())) {
                    List<String> projectIdList = StringHandlerUtil.splitStringList(operateAppPushDataVO.getProjectId());
                    for (String projectId : projectIdList) {
                        PushInfoProjectPO pushInfoProjectPO = new PushInfoProjectPO();
                        pushInfoProjectPO.setPushInfoId(pushInfoId);
                        pushInfoProjectPO.setProjectId(projectId);
                        pushInfoProjectPOList.add(pushInfoProjectPO);
                    }
                }
                if (StringUtils.isNotBlank(operateAppPushDataVO.getUserId())) {
                    List<String> userIdList = StringHandlerUtil.splitStringList(operateAppPushDataVO.getUserId());
                    for (String userId : userIdList) {
                        AppUserReadPushRecordPO appUserReadPushRecordPO = new AppUserReadPushRecordPO();
                        appUserReadPushRecordPO.setPushInfoId(pushInfoId);
                        appUserReadPushRecordPO.setUserId(userId);
                        appUserReadPushRecordPO.setStatus(DataStatusEnum.NORMAL.getType());
                        appUserReadPushRecordPO.setCreateTime(nowTime);
                        appUserReadPushRecordPO.setUpdateTime(nowTime);
                        appUserReadPushRecordPOList.add(appUserReadPushRecordPO);
                    }
                }
            }
            if (!pushInfoPOList.isEmpty()) {
                iOperatePushInfoDao.batchSavePushInfo(pushInfoPOList);
            }
            if (!pushInfoProjectPOList.isEmpty()) {
                iOperatePushInfoDao.batchSavePushInfoProject(pushInfoProjectPOList);
            }
            if (!appUserReadPushRecordPOList.isEmpty()) {
                iOperatePushInfoDao.batchSavePushInfoRead(appUserReadPushRecordPOList);
            }
        }

        return rows;
    }
}
